package it.blueocean.acanto.taglibrary.jsp.taglib.navigation;

import it.blueocean.acanto.entities.platform.DBUser;
import it.blueocean.acanto.entities.platform.MenuItem;
import it.blueocean.acanto.platform.service.NavigationService;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.TagSupport;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public abstract class NavigationTag extends TagSupport
{
	private final static Logger logger = LoggerFactory.getLogger(NavigationTag.class);

	private static final long serialVersionUID = 1L;

	private String menuId;

	private boolean expandFirst;

	private String appContext;

	private int depth;

	public NavigationTag()
	{
		menuId = null;
		expandFirst = false;
		appContext = "";
		depth = 1;
		pageContext = null;
	}

	public int getDepth()
	{
		return depth;
	}

	public void setDepth(int i)
	{
		if(i > 1)
			depth = i;
	}

	public int doStartTag() throws JspException
	{
		logger.debug("NavigationTag.doStartTag()");
		HttpServletRequest req = (HttpServletRequest) pageContext.getRequest();
		appContext = req.getContextPath();
		return 0;
	}

	public int doEndTag() throws JspException
	{
		JspWriter jspwriter = pageContext.getOut();
		
		HttpServletRequest localHttpServletRequest = (HttpServletRequest)pageContext.getRequest();
	    MenuList menulist = (MenuList)localHttpServletRequest.getSession().getAttribute("NAVIGATION_TREE");
	    
		if (menulist == null)
	    {
			DBUser user = (DBUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
			WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(pageContext.getServletContext());
			NavigationService navigationService = (NavigationService) wac.getBean("navigationService");
			
			menulist = navigationService.getFilteredMenu(user.getAuthorities());
			localHttpServletRequest.getSession().setAttribute("NAVIGATION_TREE", menulist);
	    }
		
		JspException jspexception1;
		try
		{
			if(menuId != null && !menuId.trim().equals(""))
			{
				MenuItem menuitem = menulist.getMenuItem(menuId);
				for (int i = 1; i < depth; i++)
					if(menuitem.hasSelectedChild())
						menuitem = menuitem.getSelectedChild();
				if(menuitem.getChildren().size() > 0)
					createHTML(menuitem, jspwriter);
			}
			logger.debug("NavigationTag.doEndTag()");
			return 6;
		}
		catch (NullPointerException nullpointerexception)
		{
			JspException jspexception = new JspException(
					"NullPointerException encountered while retriveing Navigation menu from session",
					nullpointerexception);
			logger.warn(jspexception.getMessage());
			throw jspexception;
		}
		catch (IOException ioexception)
		{
			jspexception1 = new JspException("IOException encountered while writing errors tag to the JspWriter.",
					ioexception);
		}
		logger.warn(jspexception1.getMessage());
		throw jspexception1;
	}

	protected String buildUrl(String s)
	{
		HttpServletResponse httpServletResponse = (HttpServletResponse) pageContext.getResponse();
		StringBuffer stringbuffer = new StringBuffer();
		stringbuffer.append(appContext)
				.append("/navigation.htm")
				.append("?")
				.append("__menu_id=").append(s).toString();

		return httpServletResponse.encodeURL(stringbuffer.toString());
	}

	protected String getHref(String s, String s1)
	{
		return (new StringBuilder())
			.append("<a href=\"").append(buildUrl(s)).append("\" >")
			.append(s1)
			.append("</a>").toString();
	}

	protected abstract void createHTML(MenuItem menuitem, JspWriter jspwriter) throws IOException;

	public boolean isExpandFirst()
	{
		return expandFirst;
	}

	public void setExpandFirst(boolean flag)
	{
		expandFirst = flag;
	}

	public String getMenuId()
	{
		return menuId;
	}

	public void setMenuId(String s)
	{
		menuId = s;
	}

}
